// 基本数据类型
package main

// func main() {
// 一. 整型  默认值 0
/*
	// 1. 普通整型  正常int占8字节  对于64位计算机 其实int 就是 int64
	var a int = 10
	fmt.Printf("%d, %T\n", a, a)

	// 2. 有符号整型：int8类型 -128~127 占用1个字节 已知变量范围可以这样用  还有int16(2)\32(4)\64(8) 返回为-2^n-1 ~ 2^n-1 - 1
	var b int8 = 98
	fmt.Printf("%d, %T\n", b, b) // 超出范围会报错

	// 3. 无符号整型：uint8类型 0~255 占用1个字节 已知变量范围可以这样用  还有uint16(2)\32(4)\64(8) 返回为0 ~ 2^n - 1
	var c uint8 = 254
	fmt.Printf("%d, %T\n", c, c)

	// 4. 大小：可以利用unsafe来查看变量大小
	fmt.Println("int8 b size", unsafe.Sizeof(b))
	fmt.Println("uint8 c size", unsafe.Sizeof(c))

	// 5. 不同长度int间的转换
	var p int32 = 10
	var q int64 = 10
	// fmt.Println(p + q) // 报错，类型不同
	fmt.Println("p + q =", p+int32(q))
	// 高转低要注意范围 int16 = 130  -->   int8 = -126. 反之无所谓

	// 6. %b %x %o
	var num int = 520
	fmt.Printf("10:%d(v:%v) to 2:%b, 16:%x, 8:%o", num, num, num, num, num)
*/

// 二. 浮点型 遵循IEEE754  %v(不保留，有多少输出多少) / %f(不满6位用0占位) 默认值 0.00000
/*
	// 1. float32  4个字节  强制保留6位小数
	var a float32 = 1.2345678
	fmt.Printf("%f, %T\n", a, a)
	fmt.Println("size", unsafe.Sizeof(a))

	// 2. float64  8个字节  强制保留6位小数
	var b float64 = 1.2345678
	fmt.Printf("%f, %T\n", b, b)
	fmt.Println("size", unsafe.Sizeof(b))

	fmt.Printf("a:%v, b:%v\n", a, b)

	// 3. float 默认的就是float64
	// var c float = 1.2345678 // 但是不能这样写，只有float32 \ float64
	c := 1.2345678 // 自动推导，会推成64的
	fmt.Printf("%f, %T\n", c, c)
	fmt.Println("size", unsafe.Sizeof(c))

	// 4. 科学计数法
	var d = 3.14e2 // 3.14 * 10^2
	fmt.Printf("%f, %v, %T\n", d, d, d)

	var e = 3.14e-2 // 3.14 * 10^-2
	fmt.Printf("%f, %v, %T\n", e, e, e)

	// 5. 精度丢失问题  可以使用第三方包，decimal
	var num float64 = 1129.6
	fmt.Println(num * 100)

	var p = 8.3
	var q = 3.8
	fmt.Println(p - q)
	res := decimal.NewFromFloat(p).Sub(decimal.NewFromFloat(float64(q))) // 加Add 减Sub 乘Mul 除Div
	fmt.Println(res)

	// 7. 类型转换
*/

// 三. 布尔类型 %t 默认值 false
// 1. 在Go中，布尔不能转换及被转换，不能参与运算，即不存在true <--> 1

// 四. 字符串类型
/*
	// 1. 定义
	var s1 string = "demo"
	var s2 = "demo"
	s3 := "demo"
	fmt.Printf("%v, %T\n", s1, s1)
	fmt.Printf("%v, %T\n", s2, s2)
	fmt.Printf("%v, %T\n", s3, s3)

	// 2. 转义 和C一样
	s4 := "C:\\Users\\len'o'v'e\\Desktop\\DatabaseCourseDesign\\GoLearn" // 路径中的 '\' 需要转义 -> \\
	fmt.Println(s4)

	// 3. 输出多行 用``
	s5 := `hello
	more line`
	fmt.Println(s5)

	// 4. 常用方法
	demo := "A,B,C"
	Chinese := "长度"
	// 长度
	fmt.Println(len(demo), len(Chinese)) // 一个汉字三个字节
	// 拼接 + / Sprintf
	fmt.Println(demo + ",D,D,E,F")
	demo = fmt.Sprintf("%s,D,D,E,F", demo)
	// 分割
	fmt.Println(strings.Split(demo, ","))
	// 判断是否包含
	fmt.Println(strings.Contains(demo, "A"), strings.Contains(demo, "G"))
	// 前后缀判断
	fmt.Println(strings.HasPrefix(demo, "A,B"), strings.HasSuffix(demo, "F"))
	// 子串位置
	fmt.Println(strings.Index(demo, "D"), strings.LastIndex(demo, "D")) // 返回D的下标 Index从头,LastIndex从尾
	// join  对象必须是一个[]string 即切片
	fmt.Println(strings.Join(strings.Split(demo, ","), "-"))

	// 5. 修改 先转换成byte / rune(有汉字,用这个) 再转回
	var s6 = "你好中国"
	fmt.Println(s6)
	rs6 := []rune(s6)
	rs6[3] = '华'
	s6 = string(rs6)
	fmt.Println(s6)
*/

// 五. byte 和 rune 类型 byte处理ASCII类型, rune处理utf8类型
/*
	var c = 'a' // 类型识别为int32
	fmt.Printf("%T, %v, %c\n", c, c, c)

	var cs = "abc" // []识别为uint8
	fmt.Printf("%T, %v, %c\n", cs[1], cs[1], cs[1])

	var c1 = '你'
	fmt.Printf("%c, %T\n", c1, c1) // %v utf8编码

	var c2 = "你好中国"
	for i, v := range c2 {
		fmt.Printf("%d, %v(%c)\n", i, v, v) // i 代表在数组中起始下标
	}
*/

// 六. 类型转换 建议低转高 不存在隐式转换 只能显式转换
/*
	// 其他类型 2 字符串 Sprintf很简单，介绍另一种方式:strconv
	a := 11
	// b := 1.1  FormatFloat(float64(data), f, -1, float64)
	// c := '1'  FormatUint(uint64, base) 意义不大
	// d := true  FormatBool(true/false)  没啥意义
	s := strconv.FormatInt(int64(a), 10) // 第一个参数必须是int64 第二个参数是进制
	fmt.Println(s)

	// 字符串 2 其他类型 strconv.ParseInt(data, out base, 64/32)\ParseFloat(data, 64/32)
	// 返回两个值，第二个值错误一般可以忽略 a, _ := strconv.Parse...
*/

// go 没有++a 有 a++ 且只能独立使用，放在一行。
// 除了这点，剩下的和一般语言都一样，看一遍就行。
// }
